<link href="../static/readme/css/application.css" media="all" rel="stylesheet" />

<div class="file_content markdown-body">

<h2>
<a id="使用说明" class="anchor" href="#%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E"></a>使用说明：</h2>
<h3>
<a id="用例编辑" class="anchor" href="#%E7%94%A8%E4%BE%8B%E7%BC%96%E8%BE%91"></a>用例编辑：</h3>
<p>可以使用页面的编辑器编写用例步骤：</p>
<p><img src="../static/readme/image/17.gif" alt="example" title="example"></p>
<h3>
<a id="1-新建用例" class="anchor" href="#1-%E6%96%B0%E5%BB%BA%E7%94%A8%E4%BE%8B"></a>1. 新建用例：</h3>
<p>用例步骤说明：</p>
<ul>
<li>每个用例步骤中通过逗号进行分隔。</li>
<li>单个步骤的格式： 步骤名称+分隔符（|）+参数列表（参数间按@@进行分隔）。如：填写|id@@kw@@selenium， 表示步骤为“填写”，参数列表为“id、kw、selenium”。</li>
<li>默认的参数含义：1：通过什么属性定位目标元素（可使用id、name、class、text、xpath、css等多种定位方式进行定位） 2：目标元素对应的属性值（如id = kw） 3：其他。</li>
<li>例如：填写|id@@kw@@selenium： 代表通过 id = kw 查找到输入框，并输入  selenium 。</li>
</ul>
<h4>
<a id="11-用例初始化" class="anchor" href="#11-%E7%94%A8%E4%BE%8B%E5%88%9D%E5%A7%8B%E5%8C%96"></a>1.1 用例初始化：</h4>
<p>初始化可以有以下方式：</p>
<ul>
<li>指定浏览器类型，如 Chrome、 Firefox。 需要对应的selenium server支持。</li>
<li>指定模拟手机型号， 如 Chrome|iPhone 6。目前只有 chrome 浏览器支持模拟手机。</li>
<li>调用其他已封装的公共方法，如 公共方法|登录。 具体的公共方法格式与正常用例一致，但需要指定用例类型为 公共用例。</li>
<li>公共方法支持嵌套，即一个公共方法里调用另一个公共方法。</li>
</ul>
<h4>
<a id="用例说明" class="anchor" href="#%E7%94%A8%E4%BE%8B%E8%AF%B4%E6%98%8E"></a>用例说明：</h4>
<h4>
<a id="一-使用chrome-浏览器进行测试" class="anchor" href="#%E4%B8%80-%E4%BD%BF%E7%94%A8chrome-%E6%B5%8F%E8%A7%88%E5%99%A8%E8%BF%9B%E8%A1%8C%E6%B5%8B%E8%AF%95"></a>一. 使用chrome 浏览器进行测试：</h4>
<p>例子：在百度中输入selenium，并验证查询结果是否正确。</p>
<div class="white"><div class="highlight"><pre><span id="LC1" class="line">Chrome,前往|http://www.baidu.com,填写|id@@kw@@selenium,点击|id@@su,验证|Web Browser Automation,截图</span></pre></div></div>
<p>步骤解析：</p>
<div class="white"><div class="highlight"><pre><span id="LC1" class="line">- Chrome： 调用 Chrome driver 进行测试。</span>
<span id="LC2" class="line">- 前往|http://www.baidu.com ：  前往目标页。</span>
<span id="LC3" class="line">- 填写|id@@kw@@selenium ：  在 id 为 kw 的元素中输入 selenium。</span>
<span id="LC4" class="line">- 点击|id@@su ： 点击 id 为 su 的元素。</span>
<span id="LC5" class="line">- 验证|Web Browser Automation ：  验证页面中是否出现 ‘Web Browser Automation’ 的文字。</span>
<span id="LC6" class="line">- 截图： 对当前页面进行截图并保存。</span></pre></div></div>
<h4>
<a id="二-使用chrome-浏览器模拟移动设备进行测试" class="anchor" href="#%E4%BA%8C-%E4%BD%BF%E7%94%A8chrome-%E6%B5%8F%E8%A7%88%E5%99%A8%E6%A8%A1%E6%8B%9F%E7%A7%BB%E5%8A%A8%E8%AE%BE%E5%A4%87%E8%BF%9B%E8%A1%8C%E6%B5%8B%E8%AF%95"></a>二. 使用chrome 浏览器模拟移动设备进行测试：</h4>
<p>例子：模拟iPhone 6 打开网页，在百度中输入selenium，并验证查询结果是否正确。</p>
<div class="white"><div class="highlight"><pre><span id="LC1" class="line">Chrome|iPhone 6,前往|http://www.baidu.com,填写|id@@kw@@selenium,点击|id@@su,验证|Web Browser Automation,截图</span></pre></div></div>
<p>步骤解析：</p>
<div class="white"><div class="highlight"><pre><span id="LC1" class="line">- Chrome|iPhone 6： 调用 Chrome driver 进行测试，并设置页面大小为模拟  iPhone 6。</span></pre></div></div>
<h3>
<a id="2公共用例" class="anchor" href="#2%E5%85%AC%E5%85%B1%E7%94%A8%E4%BE%8B"></a>2.公共用例</h3>
<p>某些公共的步骤，可以封装为公共方法进行调用：</p>
<ul>
<li>公共方法添加：新建用例，选择用例类型为 公共用例， 所属模块为public。</li>
<li>公共方法调用：步骤： 公共方法|公共方法名， 如  公共方法|登录；公共方法|查询订单。</li>
</ul>
<h4>
<a id="三-使用公共方法进行测试" class="anchor" href="#%E4%B8%89-%E4%BD%BF%E7%94%A8%E5%85%AC%E5%85%B1%E6%96%B9%E6%B3%95%E8%BF%9B%E8%A1%8C%E6%B5%8B%E8%AF%95"></a>三. 使用公共方法进行测试：</h4>
<p>例子：</p>
<ol>
<li>添加公共方法： 打开 chrome 浏览器，并打开百度首页</li>
</ol>
<div class="white"><div class="highlight"><pre><span id="LC1" class="line">// 添加公共方法： 注意需将用例类型设置为 ： 公共用例， 所属模块设置为： public， 用例名称： 打开百度首页</span>
<span id="LC2" class="line">Chrome,前往|http://www.baidu.com</span></pre></div></div>
<ol start="2">
<li>分别添加测试用例：在百度首页分别点击新闻、地图、视频，并验证跳转页面是否正确。</li>
</ol>
<div class="white"><div class="highlight"><pre><span id="LC1" class="line">公共方法|打开百度首页,点击|name@@tj_trnews,验证标题|百度新闻</span>
<span id="LC2" class="line">公共方法|打开百度首页,点击|name@@tj_trmap,验证标题|百度地图</span>
<span id="LC3" class="line">公共方法|打开百度首页,点击|name@@tj_trtieba,验证标题|百度贴吧</span></pre></div></div>
<p>步骤解析：</p>
<div class="white"><div class="highlight"><pre><span id="LC1" class="line">- 公共方法|打开百度首页： 根据所指定的用例名称，将公共用例的步骤拼接在当前用例之前执行。</span>
<span id="LC2" class="line"></span></pre></div></div>
<p>效果等同于：</p>
<div class="white"><div class="highlight"><pre><span id="LC1" class="line">Chrome,前往|http://www.baidu.com,点击|name@@tj_trnews,验证标题|百度新闻</span></pre></div></div>
<ol start="3">
<li>公共方法支持嵌套，如：</li>
</ol>
<div class="white"><div class="highlight"><pre><span id="LC1" class="line">// 公共方法1： 打开百度首页</span>
<span id="LC2" class="line">Chrome,前往|http://www.baidu.com</span>
<span id="LC3" class="line"></span>
<span id="LC4" class="line">//公共方法2： 进入百度新闻</span>
<span id="LC5" class="line">公共方法|打开百度首页,点击|name@@tj_trnews,验证标题|百度新闻</span>
<span id="LC6" class="line"></span>
<span id="LC7" class="line">// 用例： 进入百度新闻页后，点击贴吧</span>
<span id="LC8" class="line">公共方法|进入百度新闻,点击|name@@tj_trtieba,验证标题|百度贴吧</span></pre></div></div>
<p>效果等同于：</p>
<div class="white"><div class="highlight"><pre><span id="LC1" class="line">Chrome,前往|http://www.baidu.com,点击|name@@tj_trnews,验证标题|百度新闻,点击|name@@tj_trtieba,验证标题|百度贴吧</span></pre></div></div>
<h3>
<a id="3用例管理" class="anchor" href="#3%E7%94%A8%E4%BE%8B%E7%AE%A1%E7%90%86"></a>3.用例管理：</h3>
<p>还可对用例进行如下管理：</p>
<ul>
<li>用例查询</li>
<li>用例复制：新建用例时可考虑复制一条步骤类似的用例，再修改对应步骤。</li>
<li>用例删除：逻辑删除，可在数据库对应表中恢复。</li>
<li>用例执行：执行单条用例。可查看对应执行记录、截图、或重跑用例。</li>
</ul>
<h3>
<a id="4用例集管理" class="anchor" href="#4%E7%94%A8%E4%BE%8B%E9%9B%86%E7%AE%A1%E7%90%86"></a>4.用例集管理：</h3>
<ul>
<li>用例集（test suite）对应一个测试范围，可关联多个不同的用例。</li>
<li>执行用例集时会根据设置的并发数进行并发执行，提高测试效率。</li>
<li>用例集中的用例是从测试用例中复制而来，因此每个用例可以在多个不同的测试用例集中关联。</li>
<li>用例集可重跑全部用例、重跑失败用例、重跑单条用例。 注意：重跑用例时，会自动从对应测试用例中加载最新的步骤。</li>
</ul>
<h3>
<a id="5节点管理" class="anchor" href="#5%E8%8A%82%E7%82%B9%E7%AE%A1%E7%90%86"></a>5.节点管理：</h3>
<ul>
<li>节点：可加载多个selenium grid节点，系统根据当前可用节点的数量，分配用例进行执行。</li>
</ul>
<h3>
<a id="6步骤管理" class="anchor" href="#6%E6%AD%A5%E9%AA%A4%E7%AE%A1%E7%90%86"></a>6.步骤管理：</h3>
<ul>
<li>步骤：现已对大部分常见步骤进行了封装。</li>
<li>扩展封装：可根据需要进行扩展封装。</li>
<li>可直接封装selenium的方法，请参考 刷新、前往、悬浮点击 等方法。</li>
<li>可对selenium提供的方法进行二次封装，请参考 点击、填写、选择等方法。对应扩展代码可在  app/core/extend.py 文件中进行管理。</li>
</ul>
<h3>
<a id="7atx" class="anchor" href="#7atx"></a>7.atx</h3>
<ul>
<li>基于atx 进行封装，从数据库中读取需要执行的测试用例，并转化、执行、记录测试结果及截图。</li>
<li>需安装atxserver（<a href="https://github.com/openatx/atx-server">https://github.com/openatx/atx-server</a> ）</li>
</ul>
<h3>
<a id="71-android-用例组织" class="anchor" href="#71-android-%E7%94%A8%E4%BE%8B%E7%BB%84%E7%BB%87"></a>7.1. android 用例组织：</h3>
<p>样例：
Android|com.your.packagename,点击|id@@com.your.packagename:id/btn_login,等待|2,点击|name@@GuestLogin,等待|5,截图,</p>
<h3>
<a id="72-已封装步骤" class="anchor" href="#72-%E5%B7%B2%E5%B0%81%E8%A3%85%E6%AD%A5%E9%AA%A4"></a>7.2 已封装步骤：</h3>
<p>相关的步骤已封装在  app/core/atx_step.py 中，具体包括：</p>
<p>Android ： 打开指定已安装的app （通过包名）
填写： type_text
点击： click （by id/name/description/class）
截图： take_screenshot</p>
<p>由于我测试的 app 功能较为简单，目前只封装了这几个方法，如果需要可增加封装对应的方法。</p>
<h3>
<a id="8接口测试管理" class="anchor" href="#8%E6%8E%A5%E5%8F%A3%E6%B5%8B%E8%AF%95%E7%AE%A1%E7%90%86"></a>8.接口测试管理</h3>
<h4>
<a id="81-思路" class="anchor" href="#81-%E6%80%9D%E8%B7%AF"></a>8.1 思路</h4>
<ul>
<li>根据url 的固定格式，自动分隔host、url 路径、参数列表。</li>
<li>参数可进行配置为是否需要进行参数化。可以为每个参数设定对应的取值列表。</li>
<li>在页面上可直接执行测试，并查看结果。</li>
</ul>
<h4>
<a id="82-url-格式" class="anchor" href="#82-url-%E6%A0%BC%E5%BC%8F"></a>8.2 url 格式</h4>
<p>例如一个登录接口，格式为： host+api路径?参数1=值1&amp;参数2=值2
例子：
<a href="http://localhost/login/api/test.do?username=user1&amp;password=123456&amp;from=android">http://localhost/login/api/test.do?username=user1&amp;password=123456&amp;from=android</a></p>
<h4>
<a id="83-添加编辑接口" class="anchor" href="#83-%E6%B7%BB%E5%8A%A0%E7%BC%96%E8%BE%91%E6%8E%A5%E5%8F%A3"></a>8.3 添加/编辑接口</h4>
<p>添加步骤：</p>
<ul>
<li>复制具体的测试 url ，并点击 读取 按钮进行接口结构和参数列表解析。</li>
<li>修改默认解析的信息。 如名称、所属产品、模块等。</li>
<li>如果该接口需要进行签名加密，需要输入对应的签名参数列表； 如果不需要加密，留空。</li>
<li>参数列表： 如果某个参数需要进行参数化，勾选“是否参数化”，并在默认参数名列中填入对应的参数值名称（默认与参数名称一致）</li>
<li>点击保存按钮进行保存。</li>
</ul>
<p>如下图示：</p>
<p><img src="../static/readme/image/read_interface.png" alt="example2" title="读取接口信息"></p>
<h4>
<a id="84-配置具体的测试host-列表和参数列表" class="anchor" href="#84-%E9%85%8D%E7%BD%AE%E5%85%B7%E4%BD%93%E7%9A%84%E6%B5%8B%E8%AF%95host-%E5%88%97%E8%A1%A8%E5%92%8C%E5%8F%82%E6%95%B0%E5%88%97%E8%A1%A8"></a>8.4 配置具体的测试host 列表和参数列表</h4>
<p>在 app/api_new/para.py 文件中，配置对应的参数值和host 列表（如开发环境、测试环境、正式环境）。如下图示：</p>
<p><img src="../static/readme/image/setting.png" alt="example2" title="参数配置"></p>
<h4>
<a id="85-测试执行" class="anchor" href="#85-%E6%B5%8B%E8%AF%95%E6%89%A7%E8%A1%8C"></a>8.5 测试执行</h4>
<ul>
<li>如果需要在不同的测试服务器上进行测试（如开发环境、测试环境、正式环境），在 host 中下拉选择。 具体的host 配置请看  8.4 的说明。</li>
<li>如果需要修改对应参数值，直接在参数列表中修改。</li>
<li>如果需要重新计算加密值，点击 重算签名 按钮（默认使用 md5 加密，如需修改加密算法，请参考 8.6 说明进行修改）</li>
<li>点击测试 按钮进行测试。 测试结果会在页面中展示。</li>
</ul>
<p>如下图示：</p>
<p><img src="../static/readme/image/interface_detail.png" alt="example2" title="测试接口详情"></p>
<h4>
<a id="85-签名算法修改" class="anchor" href="#85-%E7%AD%BE%E5%90%8D%E7%AE%97%E6%B3%95%E4%BF%AE%E6%94%B9"></a>8.5 签名算法修改</h4>
<p>在 app/api_new/api_manage.py 文件的 getOsign 方法修改对应的签名算法：</p>
<div class="white"><div class="highlight"><pre><span id="LC1" class="line">  def getOsign(self,para_info, osignList, appkey):</span>
<span id="LC2" class="line">        """</span>
<span id="LC3" class="line">        The real osign method.</span>
<span id="LC4" class="line"></span>
<span id="LC5" class="line">        :param para_info:</span>
<span id="LC6" class="line">        :param osignList:</span>
<span id="LC7" class="line">        :param appkey:</span>
<span id="LC8" class="line">        :return:</span>
<span id="LC9" class="line">        """</span>
<span id="LC10" class="line">        paraPand = ''</span>
<span id="LC11" class="line">        print('osign list is :',osignList)</span>
<span id="LC12" class="line">        for para in osignList:</span>
<span id="LC13" class="line">            if para == 'appKey':</span>
<span id="LC14" class="line">                paraPand += appkey</span>
<span id="LC15" class="line">            else:</span>
<span id="LC16" class="line">                paraPand += str(para_info[para])</span>
<span id="LC17" class="line">                print(para_info[para])</span>
<span id="LC18" class="line">        print(paraPand)</span>
<span id="LC19" class="line">        return self.md5(paraPand)</span></pre></div></div>
<p>——————————————————————————————————————————————————————————————————————————————————————</p>
<h3>
<a id="9集成百度脑图" class="anchor" href="#9%E9%9B%86%E6%88%90%E7%99%BE%E5%BA%A6%E8%84%91%E5%9B%BE"></a>9.集成百度脑图</h3>
<p>思路：集成 kityminder-editor <a href="https://github.com/fex-team/kityminder-editor">https://github.com/fex-team/kityminder-editor</a> 框架，并将脑图的内容保存到数据库和读取展现。</p>
<h1>
<a id="常见问题" class="anchor" href="#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98"></a>常见问题：</h1>
<h3>
<a id="1没有可用的节点" class="anchor" href="#1%E6%B2%A1%E6%9C%89%E5%8F%AF%E7%94%A8%E7%9A%84%E8%8A%82%E7%82%B9"></a>1：没有可用的节点</h3>
<ul>
<li>Q： 运行用例之后会提示这个-ERROR: no hubs is availabe!</li>
<li>A： 说明没有可以使用的selenium节点执行测试。请检查是否已启动对应的 selenium server，并已配置到节点管理中，而且服务器可以正常访问该节点。</li>
</ul>
<h3>
<a id="2selenium-的浏览器被占用" class="anchor" href="#2selenium-%E7%9A%84%E6%B5%8F%E8%A7%88%E5%99%A8%E8%A2%AB%E5%8D%A0%E7%94%A8"></a>2：selenium 的浏览器被占用</h3>
<ul>
<li>Q：使用docker启动的selenium 镜像服务，如果用例执行报错， selenium grid console中的Chrome浏览器好像被置灰不可用了</li>
<li>A：这是因为如果执行报错时，没有正常退出 driver，导致对应的selenium线程持续被占用，需要等待一段时间才能释放。建议启动docker 的时候把最大进程设置为10， 这样可以并发执行，提高使用率：</li>
</ul>
<div class="white"><div class="highlight"><pre><span id="LC1" class="line">sudo docker run -e NODE_MAX_INSTANCES=10 -e NODE_MAX_SESSION=10 -d --net grid -e HUB_HOST=selenium-hub -v /dev/shm:/dev/shm selenium/node-firefox-debug</span></pre></div></div>
<h3>
<a id="3selenium-相关报错" class="anchor" href="#3selenium-%E7%9B%B8%E5%85%B3%E6%8A%A5%E9%94%99"></a>3：selenium 相关报错</h3>
<ul>
<li>Q：selenium相关报错</li>
<li>A：可能对应的 selenium server版本不支持目前使用的一些功能，建议更新到较新版本的 selenium server</li>
</ul>

</div>